﻿// cheess.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。

#include <iostream>
#include <graphics.h>
#include <math.h>

int flag = 0;//表示下棋次数；
//int index = 0;//记录胜负状态；
int board[21][21] = { 0 };
int check_level_Win(int m, int n);//横向
int check_vertical_Win(int m, int n);//纵向
int check_ZDJ_Win(int m, int n);//主对角
int check_FDJ_HXWin(int m, int n);//负对角
//void remove(int x,int y);
void initGame();
void play();
void regame();
HWND hWnd = GetHWnd();
//初始化棋盘
void initGame()
{
	//棋盘大小
	//SetWindowPos(hWnd,);
	initgraph(650, 550, SHOWCONSOLE);

	setorigin(10, 10);
	setbkcolor(DARKGRAY);
	cleardevice();
	//绘制棋盘，画线
	setlinecolor(BLACK);
	//rectangle(520, 200, 600, 230);     //(左上角x,左上角y, 右下角x，右下角y
	//outtextxy(550, 205, "悔棋");
	for (int i = 0; i <= 500; i += 25)
	{
		line(i, 0, i, 500);//line();四个参数，两个坐标；
		line(0, i, 500, i);
	}
	outtextxy(520, 50, "五子棋游戏");
	outtextxy(520, 100, "玩家一：黑");
	outtextxy(520, 150, "玩家二：白");
}

void play()
{

	int x = 0, y = 0;
	int a = 0, b = 0;
	MOUSEMSG m;//定义鼠标变量
	while (1)
	{
		m = GetMouseMsg();//获取鼠标信息;
		if (m.x > 510 || m.y > 510)
		{
			continue;
		}
		/*if (m.x > 520 && m.x <600|| m.y > 200&&m.y < 230)
		{
			remove(a,b);
			continue;
		}
		*/
		//选择正确的位置落子
		for (int i = 0; i <= 20; i++)
		{
			for (int j = 0; j <= 20; j++)
			{
				if (abs(m.x - 10 - i * 25) < 12 && abs(m.y - 10 - j * 25) < 12)
				{
					x = i * 25;
					y = j * 25;
					a = i;
					b = j;
				}
			}
		}
		if (m.uMsg == WM_LBUTTONDOWN)
		{
			//重复
			if (board[a][b] != 0)
			{
				MessageBox(hWnd, "此处已经有棋子，请重新选位置", "提示", MB_OK);//MB_OK是确定键；
				continue;
			}
			if (flag % 2 == 0)//偶数
			{
				setfillcolor(BLACK);
				solidcircle(x, y, 10);//半径为10；
				board[a][b] = 1;
				//index = checkWin(a,b);
				if (check_level_Win(a, b) || check_vertical_Win(a, b) || check_ZDJ_Win(a, b) || check_FDJ_HXWin(a, b))
				{
					MessageBox(hWnd, "游戏结束，黑子胜利!", "提示", MB_OK);
					/*board[21][21] = { 0 };
					flag = 0;
					initGame();
					*/
					//exit(0);
					regame();
					continue;
				}
			}
			else//奇数
			{
				setfillcolor(WHITE);
				solidcircle(x, y, 10);//半径为10；
				board[a][b] = 2;
				//index = checkWin(a, b);
				if (check_level_Win(a, b) || check_vertical_Win(a, b) || check_ZDJ_Win(a, b) || check_FDJ_HXWin(a, b))
				{
					MessageBox(hWnd, "游戏结束，白子胜利!", "提示", MB_OK);
					/*board[21][21] = { 0 };
					flag = 0;
					initGame();
					*/
					regame();
					//exit(0);
					continue;
				}
			}
			flag++;
		}
	}
}
//横向判断胜负
int check_level_Win(int m, int n)//传入落子的二维数组;(a,b)
{
	int count = 1;//记录连续的棋子个数；本身算一颗；
	int X = 0;
	int Y = 0;
	int colour = 0;
	colour = board[m][n];//记录该坐标是黑棋还是白棋；
	//横向向左；
	for (X = m - 1; X >= 0; X--)
	{
		if (board[X][n] == colour)
		{
			count++;
			if (count >= 5)
				return 1;
		}
		else
			break;
	}
	//横向向右；
	for (X = m + 1; X <= 20; X++)
	{
		if (board[X][n] == colour)
		{
			count++;
			if (count >= 5)
				return 1;
		}
		else
			break;
	}
	return 0;
}
int check_vertical_Win(int m, int n)//纵向判断胜负
{
	int count = 1;//记录连续的棋子个数；本身算一颗；
	int X = 0;
	int Y = 0;
	int colour = 0;
	colour = board[m][n];//记录该坐标是黑棋还是白棋；
	//纵向向上;
	for (Y = n - 1; Y >= 0; Y--)
	{
		if (board[m][Y] == colour)
		{
			count++;
			if (count >= 5)
				return 1;
		}
		else
			break;
	}
	//纵向向下;
	for (Y = n + 1; Y <= 20; Y++)
	{
		if (board[m][Y] == colour)
		{
			count++;
			if (count >= 5)
				return 1;
		}
		else
			break;
	}
	return 0;
}
int check_ZDJ_Win(int m, int n)//主对角判断胜负
{
	int count = 1;//记录连续的棋子个数；本身算一颗；
	int X = 0;
	int Y = 0;
	int colour = 0;
	colour = board[m][n];//记录该坐标是黑棋还是白棋；
	//主对角线向上;
	for (Y = n - 1, X = m + 1; Y >= 0 && X <= 20; Y--, X++)
	{
		if (board[X][Y] == colour)
		{
			count++;
			if (count >= 5)
				return 1;
		}
		else
			break;
	}
	//主对角线向下;
	for (Y = n + 1, X = m - 1; Y <= 20 && X >= 0; Y++, X--)
	{
		if (board[X][Y] == colour)
		{
			count++;
			if (count >= 5)
				return 1;
		}
		else
			break;
	}
	return 0;
}
int check_FDJ_HXWin(int m, int n)//负对角判断胜负
{
	int count = 1;//记录连续的棋子个数；本身算一颗；
	int X = 0;
	int Y = 0;
	int colour = 0;
	colour = board[m][n];//记录该坐标是黑棋还是白棋；
	//负对角线向上;
	for (Y = n - 1, X = m - 1; Y >= 0 && X >= 0; Y--, X--)
	{
		if (board[X][Y] == colour)
		{
			count++;
			if (count >= 5)
				return 1;
		}
		else
			break;
	}
	//负对角线向下;
	for (Y = n + 1, X = m + 1; Y <= 20 && X <= 20; Y++, X++)
	{
		if (board[X][Y] == colour)
		{
			count++;
			if (count >= 5)
				return 1;
		}
		else
			break;
	}
	return 0;
}

void regame()
{
	flag = 0;//表示下棋次数；
	for (int i = 0; i < 21; i++)
	{
		for (int j = 0; j < 21; j++)
		{
			board[i][j] = 0;
		}
	}
	initGame();
}

/*void remove(int x,int y)
{
	board[x][y] = 0;
	clearcircle(x,y,10);
	flag = flag - 1;
	return;
}
*/
int main()
{

	initGame();
	play();
	//std::cout << "Hello World!\n";
	return 0;
}

// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门使用技巧: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件，或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来，若要再次打开此项目，请转到“文件”>“打开”>“项目”并选择 .sln 文件
